package com.label.Service.Impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.ImmutableMap;
import com.label.Dao.PersonsCardMapper;
import com.label.Dao.PersonsDataRunStateDao;
import com.label.Dao.PersonsMapper;
import com.label.Dao.UserMapper;
import com.label.Model.Do.Persons;
import com.label.Model.Do.PersonsCard;
import com.label.Model.Do.PersonsDataRunstate;
import com.label.Model.Do.User;
import com.label.Model.Query.MessageQuery;
import com.label.Model.Query.ProcessQuery;
import com.label.Service.PersonsService;
import com.label.Utils.MailUtil;
import com.label.Utils.UserUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Component
@Transactional(rollbackFor = Exception.class)
public class PersonsServiceImpl extends ServiceImpl<PersonsMapper, Persons> implements PersonsService {

    @Resource
    private PersonsMapper personsMapper;

    @Resource
    private PersonsCardMapper personsCardMapper;

    @Resource
    private PersonsDataRunStateDao personsDataRunStateDao;

    @Resource
    private UserMapper userMapper;

    @Resource
    @Qualifier("sparkSqlJdbcTemplate")
    private JdbcTemplate sparkJdbc;

    @Resource
    @Qualifier("oracleJdbcTemplate")
    private JdbcTemplate oracleJdbc;

    @Resource
    @Qualifier("hiveJdbcTemplate")
    private JdbcTemplate hiveJdbc;


    @Override
    public List<Persons> getOne(Persons persons) {
        return personsMapper.getPersonsById(persons.getId());
    }

    @Override
    public List<Persons> getAll() {
        return personsMapper.getPersonsById(null);
    }

    @Override
    public List<Persons> getMy(){
        List<Persons> persons=personsMapper.getPersonsById(null);
        User user=userMapper.getUserById(UserUtil.getUserId()).get(0);
        System.out.println(user);
        switch (user.getOpLevel()){
            case "0":return persons;
            case "1":return persons.stream().filter(p->p.getAuth().equals("1")||p.getAuth().equals("2")||(p.getAuth().equals("0")&&p.getAuthor().equals(user.getUserName()))).collect(Collectors.toList());
            case "2":return persons.stream().filter(p->p.getAuth().equals("2")||(p.getAuth().equals("0")&&p.getAuthor().equals(user.getUserName()))).collect(Collectors.toList());
            default:return null;
        }
    }

    @Override
    public Long addPersons(Persons persons) {
        if(!personsMapper.selectList(new QueryWrapper<Persons>().lambda().eq(Persons::getName,persons.getName()).eq(Persons::getState,"1")).isEmpty()){
            return null;
        }
        personsMapper.insert(persons);
        if(persons.getCards()!=null&&!persons.getCards().isEmpty()){
            for(PersonsCard p:persons.getCards()){
                p.setPersonsId(persons.getId());
                personsCardMapper.insert(p);
            }
        }
        return persons.getId();
    }

    @Override
    public Boolean deletePersonsById(Long Id) {
        Persons personsTemp=personsMapper.selectById(Id);
        if(personsTemp==null||personsTemp.getState().equals("0"))
            return false;
        if(!oracleJdbc.queryForList("select * from PERSONAS_BOARD where PERSONAS_ID='"+Id+"'").isEmpty())
            return false;
        Persons persons=new Persons(Id);
        persons.setState("0");
        return personsMapper.updateById(persons) == 1;
    }

    @Override
    public Boolean resumePersonsById(Long Id) {
        Persons personsTemp=personsMapper.selectById(Id);
        if(personsTemp==null||personsTemp.getState().equals("1"))
            return false;
        Persons persons=new Persons(Id);
        persons.setState("1");
        return personsMapper.updateById(persons) == 1;
    }

    @Override
    public Boolean deletePersonsByIdReal(Long Id) {
        Persons personsTemp=personsMapper.selectById(Id);
        if(personsTemp==null)
            return false;
        personsMapper.deleteById(Id);
        personsCardMapper.delete(new QueryWrapper<PersonsCard>().lambda().eq(PersonsCard::getPersonsId,Id));
        return true;
    }

    @Override
    public Boolean updatePersonsById(Persons persons){
        Persons personsTemp=personsMapper.selectById(persons.getId());
        if(personsTemp==null||personsTemp.getState().equals("0"))
            return false;
        if(!BeanUtil.isEmpty(persons,"cards","id")){
            personsMapper.updateById(persons);
        }
        if(persons.getCards()!=null&&!persons.getCards().isEmpty()){
            personsCardMapper.delete(new QueryWrapper<PersonsCard>().lambda().eq(PersonsCard::getPersonsId,persons.getId()));
            for(PersonsCard p:persons.getCards()){
                p.setPersonsId(persons.getId());
                personsCardMapper.insert(p);
            }
        }
        return true;
    }

    @Override
    public Boolean cheakPersonsName(String name) {
        List<String> personsName=personsMapper.getPersonsById(null).stream().map(Persons::getName).collect(Collectors.toList());
        return personsName.contains(name);
    }

    @Override
    public Boolean savePersonasData(ProcessQuery processQuery) throws Exception{
        try{
            if(!StringUtils.isBlank(processQuery.getRealId())) { // realId不为空
                Persons persons=new Persons(Long.valueOf(processQuery.getRealId()),"3");
                personsMapper.updateById(persons);

                if(!StringUtils.isBlank(processQuery.getTempId())) { //realId存在&&tempId存在 保存  realId先删，再将临时tempId改为realId 分区重命名（操作：查询之后保存）   保留的还是原始的realid，但换成了真实数据
//                    deletePersonasData(process
//                    Query.getRealId()); //删除原画像的数据
//                    persons.setCount(savePersonsData(processQuery.getRealId(), "select entityid,theme,'' as time from personportraitdatapar where portraitid='"+processQuery.getTempId()+"'",processQuery.getTheme()));
//                    deletePersonasData(processQuery.getTempId());
                    oracleJdbc.execute("delete personportraitdatapar where portraitid ='"+processQuery.getRealId()+"'");
                    oracleJdbc.execute("update personportraitdatapar set portraitid='"+processQuery.getRealId()+"' where portraitid='"+processQuery.getTempId()+"'");
                } else { //realId存在&&tempId不存在null   即为刷新
                    persons.setCount(dataProcess(processQuery.getRealId(),processQuery.getSql(),processQuery.getTheme()));
                    personsDataRunStateDao.deleteById(Long.valueOf(processQuery.getRealId()));
                }

                persons.setRun_finish_state("1");
                personsMapper.updateById(persons);

                personsDataRunStateDao.insert(new PersonsDataRunstate(persons.getId(),"0","1",processQuery.getTheme()));
            }
            else if(!StringUtils.isBlank(processQuery.getTempId())){//realId不存在tempId存在 即为查询
                dataProcess(processQuery.getTempId(),processQuery.getSql(),processQuery.getTheme());
            }else {
                return false;
            }
            return true;
        } catch(Exception e) {
            if(!StringUtils.isBlank(processQuery.getRealId())) {// realId不为空  (保存或刷新)
                personsMapper.updateById(new Persons(Long.valueOf(processQuery.getRealId()),"2"));
            }
            throw e;
        }
    }

    @Override
    public Boolean deletePersonasData(String id) throws IOException{  // 删除画像数据
//        HdfsFileUtil.delete("/databases/studentprofile/personportraitdatapar/"+id);
//        String deletePartition = "ALTER TABLE hive.personportraitdatapar DROP IF EXISTS PARTITION (portraitid =  '" + id + "')";
//        sparkJdbc.execute(deletePartition);
        oracleJdbc.execute("delete personportraitdatapar where portraitid ='"+id+"'");
        return true;
    }

    private String savePersonsData(String id,String sql,String theme) {  // 保存画像数据
//        String partition = "alter table hive.personportraitdatapar add if not exists partition (portraitid="+ id+") location '"+id+"'";
//        String insertSql="insert overwrite table hive.personportraitdatapar partition (portraitid="+id+") "+sql;
//
//        sparkJdbc.execute(partition);
//        sparkJdbc.execute(insertSql);
//        sparkJdbc.execute("refresh table hive.personportraitdatapar");
//
//        String countSql="select count(*) as count from hive.personportraitdatapar where portraitid="+id+" and theme='"+theme+"'";
//        String totalSql="select count(*) as count from "+theme;
//        Map<String,Object> count=sparkJdbc.queryForMap(countSql);
//        Map<String,Object> total=sparkJdbc.queryForMap(totalSql);


        oracleJdbc.execute("delete personportraitdatapar where portraitid ='"+id+"'");
        oracleJdbc.execute("insert into table personportraitdatapar "+sql);


        String countSql="select count(*) as count from personportraitdatapar where portraitid="+id+" and theme='"+theme+"'";
//        String totalSql="select count(*) as count from "+theme;
        Map<String,Object> count=oracleJdbc.queryForMap(countSql);
//        Map<String,Object> total=oracleJdbc.queryForMap(totalSql);

        return JSONObject.toJSONString(ImmutableMap.of("count",count.get("COUNT"),"total",0));
    }

    @Override
    public String dataProcess(String id, String sql, String theme) throws Exception{
        try{
            String entityname="";
            switch (theme){
                case "studentprofile":entityname="userid";break;
                case "dormitoryprofile":entityname="dormitory";break;
                case "classprofile":entityname="classid";break;
                case "majorprofile":entityname="majorid";break;
                case "unitprofile":entityname="united";break;
                case "courseprofile":entityname="courseid";break;
            }

//            sql="select "+entityname+" from ("+sql+") temp group by "+entityname;
//
//            String partition = "alter table hive.personportraitdatapar add if not exists partition (portraitid="+ id+") location '"+id+"'";
//            String insertSql="";
//            if(theme.equals("studentprofile"))
//                insertSql = "insert overwrite TABLE hive.personportraitdatapar partition (portraitid="+id+") select K.*,'"+theme+"' as theme,'' as time  from (" + sql+ ") K";
//            else
//                insertSql = "insert into TABLE hive.personportraitdatapar partition (portraitid="+id+") select K.*,'"+theme+"' as theme,'' as time  from (" + sql+ ") K";
//
//            sparkJdbc.execute(partition);
//            sparkJdbc.execute(insertSql);
//            sparkJdbc.execute("refresh table hive.personportraitdatapar");
//
//            String countSql="select count(*) as count from hive.personportraitdatapar where portraitid="+id;
//            Map<String,Object> result=sparkJdbc.queryForMap(countSql);
//            return result.get("count").toString();

            sql="select "+entityname+" from ("+sql+") temp group by "+entityname;

            String insertSql="";
            if(theme.equals("studentprofile")){
                oracleJdbc.execute("delete personportraitdatapar where portraitid ='"+id+"'");
            }
            oracleJdbc.execute("insert into personportraitdatapar  select '"+id+"',K.*,'"+theme+"' as theme from (" + sql+ ") K");


            String countSql="select count(*) as count from personportraitdatapar where portraitid="+id;
            Map<String,Object> result = oracleJdbc.queryForMap(countSql);
            return result.get("count").toString();
        } catch(Exception e) {
            e.printStackTrace();
            throw new Exception();
        }
    }

    @Override
    public Boolean sendMessage(MessageQuery messageQuery) {
        return MailUtil.sendParents(messageQuery);
    }

    @Override
    public Boolean sendMessage2(MessageQuery messageQuery, MultipartFile file) throws IOException {
        return MailUtil.sendParents2(messageQuery,file);
    }

    @Override
    public List<Persons> getMyByTheme(String theme){
        String entityname="";
        switch (theme){
            case "studentprofile":entityname="userid";break;
            case "dormitoryprofile":entityname="dormitory";break;
            case "classprofile":entityname="classid";break;
            case "majorprofile":entityname="majorid";break;
            case "unitprofile":entityname="united";break;
            case "courseprofile":entityname="courseid";break;
        }

        List<Persons> persons=personsMapper.getPersonsById(null);
        User user=userMapper.getUserById(UserUtil.getUserId()).get(0);
        System.out.println(user);
        switch (user.getOpLevel()){
            case "0":return persons;
            case "1":
                String finalEntityname = entityname;
                return persons.stream().filter(p->(p.getAuth().equals("1")||p.getAuth().equals("2")||(p.getAuth().equals("0")&&p.getAuthor().equals(user.getUserName())))&&p.getTheme().equals(finalEntityname)).collect(Collectors.toList());
            case "2":
                String finalEntityname1 = entityname;
                return persons.stream().filter(p->(p.getAuth().equals("2")||(p.getAuth().equals("0")&&p.getAuthor().equals(user.getUserName())))&&p.getTheme().equals(finalEntityname1)).collect(Collectors.toList());
            default:return null;
        }
    }


}
